﻿using Castle.MicroKernel.Registration;
using Castle.Windsor;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.InterceptionExtension;
using Sapit.Windsor;

namespace ClientApplication
{
    public static class ServiceProvider
    {
        public static IWindsorContainer IWC { private get; set; }
        public static IUnityContainer IUC { private get; set; }

        static ServiceProvider()
        {
            InitializeWindsor();
            initializeUnity();
        }

        private static void InitializeWindsor()
        {
            Castle.Windsor.WindsorContainer ioc = new Castle.Windsor.WindsorContainer();
            ServiceProvider.IWC = ioc;
            ioc.Register(Component.For<Sapit.Windsor.CacheInterceptor<string>>());
            ioc.Register(Component.For<Sapit.Windsor.CircuitBreakerInterceptor>());
            ioc.Register(Component.For<Sapit.Windsor.ResponseTimeThrottleInterceptor>());
            ioc.Register(Component.For<Sapit.Windsor.TimeoutInterceptor>());
            ioc.Register(Component.For<Sapit.Windsor.RetryInterceptor>());
            ioc.Register(Component.For<IFirstServiceProxyWindsor>().ImplementedBy<FirstServiceProxyWindsor>()
                .Interceptors<Sapit.Windsor.CacheInterceptor<string>>()
                .Interceptors<Sapit.Windsor.CircuitBreakerInterceptor>()
                .Interceptors<Sapit.Windsor.ResponseTimeThrottleInterceptor>()
                .Interceptors<Sapit.Windsor.TimeoutInterceptor>()
                .Interceptors<Sapit.Windsor.RetryInterceptor>());
            var x = ServiceProvider.Resolve<CacheInterceptor<string>>();
            var y = ServiceProvider.Resolve<CircuitBreakerInterceptor>();
            var z = ServiceProvider.Resolve<ResponseTimeThrottleInterceptor>();
            var v = ServiceProvider.Resolve<TimeoutInterceptor>();
        }

        private static void initializeUnity()
        {
            IUnityContainer container = new UnityContainer();
            ServiceProvider.IUC = container;
            container.AddNewExtension<Interception>();
            container.RegisterType<IFirstServiceProxyUnity, FirstServiceProxyUnity>();
            container.Configure<Interception>().SetInterceptorFor<IFirstServiceProxyUnity>(new TransparentProxyInterceptor());
        }

        public static T Resolve<T>()
        {
            return IWC.Resolve<T>();
        }

        public static IFirstServiceProxyPostSharp Resolve()
        {
            return new FirstServiceProxyPostSharp();
        }

        public static T ResolveUnity<T>()
        {
            return IUC.Resolve<T>();
        }
    }
}
